﻿/*
 * 作者: 谢中涞,博客园:http://www.cnblogs.com/xie-zhonglai
 * 欢迎转载,但请保留出处
 * */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Liya.Crm.Core
{
    /// <summary>
    /// 带有逻辑运算的查询表达式
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class LogicEFExpression<T> : EFExpression<T> where T : class
    {
        private EFExpression<T> left;
        private EFExpression<T> right;
        private ELogicType logicType;

        /// <summary>
        /// 实例化新的逻辑运算查询表达式
        /// </summary>
        /// <param name="left"></param>
        /// <param name="logicType">逻辑运算类型</param>
        /// <param name="right"></param>
        public LogicEFExpression(EFExpression<T> left, ELogicType logicType, EFExpression<T> right)
        {
            if (left == null || right == null)
                throw new ArgumentNullException("left 和 right 不能同时为空");
            this.left = left;
            this.right = right;
            this.logicType = logicType;
        }

        public override Expression<Func<T, bool>> GetExpression()
        {
            if (left == null)
                return right.GetExpression();
            else if (right == null)
                return left.GetExpression();
            else
            {
                //判断进行运算的两个条件是否为空
                if (left is EmptyEFExpression<T> && right is EmptyEFExpression<T>)
                    return left.GetExpression();
                else if (left is EmptyEFExpression<T>)
                    return right.GetExpression();
                else if (right is EmptyEFExpression<T>)
                    return left.GetExpression();

                var leftExp = left.GetExpression();
                var rightExp = right.GetExpression();
                Expression<Func<T, bool>> exp = null;

                if (leftExp == null && rightExp == null)
                    return new EmptyEFExpression<T>().GetExpression();
                else
                {
                    if (leftExp == null)
                        return rightExp;
                    else if (rightExp == null)
                        return leftExp;
                    else
                    {
                        switch (logicType)
                        {
                            case ELogicType.And:
                                exp = leftExp.And(rightExp);
                                break;
                            case ELogicType.Or:
                                exp = leftExp.Or(rightExp);
                                break;
                            default:
                                break;
                        }
                    }
                }
                return exp;
            }
        }

        internal override Expression Expression
        {
            get
            {
                return null;
            }
        }
    }
}
